package com.chengqs.leetcode.hot100;

import com.chengqs.leetcode.utils.DataGeneratorUtil;
import com.chengqs.leetcode.utils.TimeCostUtil;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 哈希<br>
 * 数组、哈希表<br>
 * 简单
 *
 * <h1>1. 两数之和</h1>
 *
 * <p>给定一个整数数组 nums 和一个整数目标值 target，请你在该数组中找出 和为目标值 target  的那 两个 整数，并返回它们的数组下标。</p>
 *
 * <p>你可以假设每种输入只会对应一个答案，并且你不能使用两次相同的元素。</p>
 *
 * <p>你可以按任意顺序返回答案。</p>
 */
public class A01TwoSum {
    public static void main(String[] args) {
        int[] array = new int[]{2, 7, 11, 15};
        int target = 9;

        A01TwoSum twoSum = new A01TwoSum();

        System.out.println("基础数据");
        TimeCostUtil.timeCost("两数之和-暴力解法", () -> twoSum.solution1(array, target));
        TimeCostUtil.timeCost("两数之和-哈希表解法", () -> twoSum.solution2(array, target));

        int[] array2 = DataGeneratorUtil.generateRandomIntArray(100000000, 1, 100000000);
        int target2 = array2[new Random().nextInt(array2.length)] + array2[new Random().nextInt(array2.length)];
        System.out.println("大数据量");
        TimeCostUtil.timeCost("两数之和-暴力解法", () -> twoSum.solution1(array2, target2));
        TimeCostUtil.timeCost("两数之和-哈希表解法", () -> twoSum.solution2(array2, target2));
    }

    // 暴力枚举
    public int[] solution1(int[] nums, int target) {
        int n = nums.length;
        for (int i = 0; i < n; ++i) {
            for (int j = i + 1; j < n; ++j) {
                if (nums[i] + nums[j] == target) {
                    return new int[]{i, j};
                }
            }
        }
        return new int[0];
    }

    // 哈希表
    public int[] solution2(int[] nums, int target) {
        Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; ++i) {
            if (hashtable.containsKey(target - nums[i])) {
                return new int[]{hashtable.get(target - nums[i]), i};
            }
            hashtable.put(nums[i], i);
        }
        return new int[0];
    }
}
